package montecarloSinglethread;

import java.util.*;


public class SingleThreadMontCarlo 
{

	private	double currentPrice;
	private	double strikePrice;
	private	double maturityTime;
	private	double discountRate;
	private	double carryRate;
	private	double volatility;
	private	int numSteps;
	private	int numSimulations;
	private	double z;
	
	//Montecarlo function
	public double montecarlo(){
		
		
		double dt,St;
		double Sum=0, Drift,vSqrdt;
		int i,j;
		 
		//initialization variables
		dt=maturityTime/numSteps;
		Drift=(carryRate-volatility*volatility/2)*dt;
		vSqrdt=volatility*Math.sqrt(dt);

		
		//begin simulation
		for(i=1;i<=numSimulations;i++){
			
			//initialize random
			Random rand = new Random();
			
			//calcul
			St=currentPrice;
			for(j=1;j<=numSteps;j++){
				St=St*Math.exp(Drift+vSqrdt*rand.nextGaussian());
				
			}
			Sum=Sum+Math.max(z*(St-strikePrice), 0);
		}
		
		return Math.exp(-discountRate*maturityTime)*(Sum/numSimulations);
	}

	
	//Constructors 
	public SingleThreadMontCarlo(){	//default constructor
		currentPrice=40;
		strikePrice=50;
		discountRate=0.06;
		maturityTime=0.5;
		carryRate=0.1;
		volatility=0.45;
		numSteps=168;
		numSimulations=100000;
		z=1;
	}
	
	
	public SingleThreadMontCarlo(String CallPutFlag, double currentPrice, double strikePrice, 
			double maturityTime,double discountRate,double carryRate,double volatility, int numSteps,
			int numSimulations){
		this.currentPrice=currentPrice;
		this.strikePrice=strikePrice;
		this.discountRate=discountRate;
		this.maturityTime=maturityTime;
		this.carryRate=carryRate;
		this.volatility=volatility;
		this.numSteps=numSteps;
		this.numSimulations=numSimulations;
		if(CallPutFlag.contains("c")){
			this.z=1;
		}
		else if(CallPutFlag.contains("p")){
			this.z=-1;
		}
		else{
			this.z=0;
		}
	}
	
}